package com.braveo.dict.creator.app.folder;

import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.apache.commons.io.FileUtils;

import com.braveo.dict.creator.common.DictDb;
import com.braveo.dict.creator.common.DictDbSQLite3DAO;
import com.braveo.dict.creator.common.ImageEntry;
import com.braveo.dict.creator.common.WordEntry;

public class FolderApp {
	
	static Options createOptions() {
		Options options = new Options();
		options.addOption(new Option("d", true, "Base Directory"));
		options.addOption(new Option("o", true, "Output file/Database file"));
		
		return options;
	}
	
	static void usage(Options options) {
		HelpFormatter formatter = new HelpFormatter();
		formatter.printHelp(FolderApp.class.getName(), options);
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		CommandLineParser parser = new PosixParser();
		Options options = createOptions();
		File inputFolder = null;
		File outputFile = null;
		
		try {
			CommandLine line = parser.parse(options, args);
			if(line.hasOption("d")) {
				String value = line.getOptionValue("d");
				inputFolder = new File(value);
				if(!inputFolder.exists() || !inputFolder.isDirectory()) {
					System.err.println("Error: " + inputFolder.getPath() + " does not exist or is not a directory");
					System.exit(1);
				}
			} else {
				usage(options);
				System.exit(1);
			}
			
			if(line.hasOption("o")) {
				String value = line.getOptionValue("o");
				outputFile = new File(value);
				if(outputFile.exists()) {
					System.err.println("Warning: " + outputFile.exists());
				}
			}
			else {
				usage(options);
				System.exit(1);
			}
				
		} catch (ParseException ex) {
			System.err.println("Parseing failed. Reason: " + ex.getMessage());
			usage(options);
			System.exit(1);
		}
		
		processFolder(inputFolder, outputFile);
	}

	public static void processFolder(File inputFolder, File outputFile) throws Exception {
		
		File[] targetSubFolders = inputFolder.listFiles(new FileFilter() {
			
			@Override
			public boolean accept(File pathname) {
				if(!pathname.isDirectory())
					return false;
				return true;
			}
		});
		
		if(targetSubFolders.length == 0) {
			return;
		}
		
		DictDb db = new DictDbSQLite3DAO(outputFile);
		db.openDatabase();

		ArrayList<WordEntry> wordList = new ArrayList<WordEntry>();
		
		for(File sub : targetSubFolders) {
			WordEntry we = new WordEntry();
			we.setWord(sub.getName());
			
			File exFile = new File(sub, "ex.txt");
			if(!exFile.exists())
				we.setExplanation("");
			else {
				we.setExplanation(FileUtils.readFileToString(exFile));
			}
			
			final List<String> allTypes = ImageFileUtils.getAllSuffix();
			File [] imageFiles = sub.listFiles(new FileFilter() {
				
				@Override
				public boolean accept(File pathname) {
					if(!pathname.isFile())
						return false;
					
					String fileName = pathname.getName().toLowerCase();
					int pos = fileName.lastIndexOf('.');
					if(pos == -1)
						return false;
					String suffix = fileName.substring(pos+1);
					for(String type : allTypes) {
						if(type.equals(suffix)) {
							return true;
						}
					}
					return false;
				}
			});
			
			for(File imageFile : imageFiles) {
				if(imageFile.length() > 1024 * 1024) {
					System.err.println("Too big : " + imageFile.getPath() + " / " + imageFile.length());
				}
				String fileName = imageFile.getName();
				int pos = fileName.lastIndexOf('.');
				if(pos == -1)
					continue;
				String suffix = fileName.substring(pos+1);

				ImageEntry ie = new ImageEntry();
				ie.setFileName(fileName);								
				ie.setMimeType(ImageFileUtils.getMimeType(suffix));
				ie.setImageData(FileUtils.readFileToByteArray(imageFile));
				we.getImageList().add(ie);
			}
			
			wordList.add(we);
				
			if(wordList.size() > 1000) {
				db.addWords(wordList);
				wordList.clear();
			}
		}
		
		db.addWords(wordList);
		
		db.closeDatabase();
	}

}
